﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Reflection;
using CWB.Web.Configuration;

namespace CWB.WebSite
{
    public class LanguageControllerFactory : IControllerFactory
    {
        private static readonly Dictionary<string, Type> typeCache = new Dictionary<string, Type>();
        private static readonly object typeCacheSyncRoot = new object();

        private static IController CreateController(RequestContext context, Type controllerType)
        {
            try
            {
                if (context.RouteData.Values["culture"] != null)
                {
                    string culture = context.RouteData.Values["culture"].ToString();
                    if (!string.IsNullOrEmpty(culture))
                    {
                        var language = AppConfigManager.LanguageInfos.FirstOrDefault(l => l.CultureName.Equals(culture, StringComparison.InvariantCultureIgnoreCase));
                        Thread currentThread = Thread.CurrentThread;
                        currentThread.CurrentCulture = new CultureInfo(language.CultureName);
                        currentThread.CurrentUICulture = currentThread.CurrentCulture;
                        currentThread.CurrentCulture.NumberFormat = CultureInfo.GetCultureInfo("en-gb").NumberFormat;
                        currentThread.CurrentCulture.DateTimeFormat = CultureInfo.GetCultureInfo("en-gb").DateTimeFormat;

                        return (IController)Activator.CreateInstance(controllerType, language);
                    }
                }
                return (IController)Activator.CreateInstance(controllerType);
            }
            catch (ArgumentNullException)
            {
                throw new HttpException(404, "");
            }
        }

        IController IControllerFactory.CreateController(RequestContext context, string controllerName)
        {
            string strNameSpace = GetType().Namespace;
            Type controllerType;
            if (!typeCache.TryGetValue(controllerName, out controllerType))
            {
                lock (typeCacheSyncRoot)
                {
                    if (!typeCache.TryGetValue(controllerName, out controllerType))
                    {
                        controllerType = Type.GetType(string.Format("{0}.Controllers.{1}Controller", strNameSpace, controllerName), false, true) ??
                                         Type.GetType(string.Format("{0}.Controllers.Service.{1}Controller", strNameSpace, controllerName), false, true);

                        if (controllerType == null)
                        {
                            throw new Exception(string.Format("Can't find controler [{0}]", controllerName));
                        }

                        typeCache.Add(controllerName, controllerType);
                    }
                }
            }
            return CreateController(context, controllerType);
        }

        void IControllerFactory.ReleaseController(IController controller)
        {
            if (controller is IDisposable)
                ((IDisposable)controller).Dispose();
        }
    }
}
